﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using Interface.DAO;
using OR;
using JMI_Nucleo.Classe;
using JMI_Nucleo.JMIProvider;
using JMI_Nucleo.Enumerador;
using System.Text;

namespace Dao
{
    public class IBGEDao : IIBGEDao<mIBGE>
    {
        private string cmdSQL;
        private mIBGE infoIBGE;
        private UtilSQL utilSQL;

        #region Comando SQL
        const string cmdInsertSQL = @"INSERT INTO cadastro.ibge(datacadastro, empresa, usuario, dataalteracao, ativo, 
                                      codigo, numero, municipio, coduf, uf)
                                      VALUES (@datacadastro, @empresa, @usuario, @dataalteracao, @ativo, 
                                      @codigo, @numero, @municipio, @coduf, @uf)";

        const string cmdUpdateSQL = @"UPDATE cadastro.ibge SET datacadastro=@datacadastro, usuario=@usuario, 
                                      dataalteracao=@dataalteracao, ativo=@ativo, numero=@numero, municipio=@municipio, 
                                      coduf=@coduf, uf=@uf
                                      WHERE codigo =@PAR_IBGE AND empresa =@PAR_EMPRESA";

        const string cmdDeleteSQL = @"DELETE FROM cadastro.ibge
                                      WHERE codigo =@PAR_IBGE AND empresa =@PAR_EMPRESA";

        const string cmdSelectSQL = @"SELECT datacadastro, empresa, usuario, dataalteracao, ativo, codigo, numero, 
                                      municipio, coduf, uf FROM cadastro.ibge";


        #endregion
        public IBGEDao()
        {
            cmdSQL = String.Empty;

            utilSQL = new UtilSQL();
            utilSQL.Schema = "cadastro";
            utilSQL.Tabela = "ibge";
            utilSQL.CampoChave = "codigo";
        }
  
        #region Metodos publicos
        void IIBGEDao<mIBGE>.InserirBlocoSQL(List<string> lstValor)
        {
            int proximoID = 0;
            string _tabela = String.Empty;
            // Para gerar o comando SQL precisa conectar e desconectar do banco de dados
            utilSQL.Conexao = EngineBD.GetConexao;
            utilSQL.Tabela = "ibge";
            utilSQL.Schema = "cadastro";
            utilSQL.CodigoEmpresa = 1; // por enquanto esta fixo

            string _sql = String.Empty;
            _tabela = utilSQL.Schema + "." + utilSQL.Tabela;
            proximoID = EngineBD.GetID(_tabela, "codigo", utilSQL.CodigoEmpresa);
            _sql = GetComandoInsertBlocoSQL(lstValor, proximoID, false);

            EngineBD.ExecuteEmBloco(_sql);
        }

        bool IIBGEDao<mIBGE>.Inserir(mIBGE infoIBGE)
        {
            bool sucesso = false;
            try
            {
                DbCommand _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdInsertSQL;
                GeraParametro(ref _cmd, infoIBGE);
                _cmd.Prepare();

                sucesso = EngineBD.ExecuteNonQuery(_cmd);
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "bool IIBGEDao<mIBGE>.Inserir(mIBGE infoIBGE)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            return sucesso;
        }
        bool IIBGEDao<mIBGE>.Alterar(mIBGE infoIBGE)
        {
            bool sucesso = false;
            DbParameter p = null;

            try
            {
                DbCommand _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdUpdateSQL;
                GeraParametro(ref _cmd, infoIBGE);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_IBGE";
                p.Value = infoIBGE.Codigo;
                _cmd.Parameters.Add(p);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_EMPRESA";
                p.Value = infoIBGE.Empresa;
                _cmd.Parameters.Add(p);

                _cmd.Prepare();

                sucesso = EngineBD.ExecuteNonQuery(_cmd);                
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "bool IIBGEDao<mIBGE>.Alterar(mIBGE infoIBGE)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            return sucesso;
        }
        bool IIBGEDao<mIBGE>.Excluir(int Codigo)
        {
            bool sucesso = false;
            DbParameter p = null;

            try
            {
                DbCommand _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdDeleteSQL;

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_IBGE";
                p.Value = infoIBGE.Codigo;
                _cmd.Parameters.Add(p);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_EMPRESA";
                p.Value = infoIBGE.Empresa;
                _cmd.Parameters.Add(p);

                _cmd.Prepare();

                sucesso = EngineBD.ExecuteNonQuery(_cmd);       
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "bool IIBGEDao<mIBGE>.Excluir(int Codigo)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            return sucesso;
        }

        mIBGE IIBGEDao<mIBGE>.GetIBGE(int Codigo)
        {
            infoIBGE = new mIBGE();
            DbDataReader rd = null;
            DbCommand _cmd = null;
            DbParameter p = null;

            try
            {
                _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdSelectSQL;

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_IBGE";
                p.Value = Codigo;
                _cmd.Parameters.Add(p);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_EMPRESA";
                p.Value = 1; // Criar metodo empresa logada
                _cmd.Parameters.Add(p);

                rd = EngineBD.ExecuteDataReader(_cmd);

                if (rd.Read())
                    infoIBGE = GetRdIBGE(rd);
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "mIBGE IIBGEDao<mIBGE>.GetIBGE(int Codigo)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            finally
            {
                rd.Close();
            }
            return infoIBGE;
        }

        bool IIBGEDao<mIBGE>.TabelaCarregada()
        {
            bool retorno = false;
            DbDataReader rd = null;
         
            try
            {
                string cmdSQL = String.Empty;

                utilSQL.Conexao = EngineBD.GetConexao;
                cmdSQL = utilSQL.GeraSimpleSQL(null);
                //rd = EngineBD.ExecuteDataReader(cmdSQL);
                if (rd.Read())
                    retorno = true;
            }
            finally
            {
                if (rd != null)
                    rd.Close();
            }
            return retorno;
        }

        List<mIBGE> IIBGEDao<mIBGE>.GetListIBGE()
        {
            List<mIBGE> lstIBGE = new List<mIBGE>();
            DbDataReader rd = null;
            DbCommand _cmd = null;
            string cmdSQL = String.Empty;

            try
            {
                cmdSQL = cmdSelectSQL;
                cmdSQL += " ORDER BY municipio";
                _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdSQL;

                rd = EngineBD.ExecuteDataReader(_cmd);

                while (rd.Read())
                {
                    infoIBGE = GetRdIBGE(rd);
                    lstIBGE.Add(infoIBGE);
                }
            }
            finally
            {
                if (rd != null)
                    rd.Close();
            }
            return lstIBGE;
        }
        #endregion

        #region Metodos privados
        private DataTable GetSchema()
        {
            DbDataReader dr = null;
            DbCommand comando = null;
            DataTable schema = null;
            try
            {
                comando = EngineBD.GetConexao.CreateCommand();
                comando.CommandType = CommandType.Text;
                comando.CommandText = "SELECT * FROM cadastro.ibge";
                dr = comando.ExecuteReader(CommandBehavior.KeyInfo);
                schema = dr.GetSchemaTable();
            }
            finally
            {
                dr.Close();
                comando.Dispose();
            }
            return schema;
        }
        private mIBGE GetRdIBGE(DbDataReader rd)
        {
            infoIBGE = new mIBGE();

            infoIBGE.Codigo = Convert.ToInt32(rd["codgio"]);
            infoIBGE.DataCadastro = Convert.ToDateTime(rd["datacadastro"]);
            infoIBGE.DataAlteracao = Convert.ToDateTime(rd["dataalteracao"]);
            infoIBGE.Ativo = Convert.ToBoolean(rd["ativo"]);
            infoIBGE.Numero = Convert.ToInt32(rd["numero"]);
            infoIBGE.Municipio = rd["municipio"].ToString();
            infoIBGE.CodUF = Convert.ToInt16(rd["coduf"]);
            infoIBGE.UF = rd["uf"].ToString();

            return infoIBGE;
        }
  
        private string GetComandoInsertBlocoSQL(List<string> lstValor, int ProximoID, bool UsaSequenciador = false)
        {
            string nomeCampo = String.Empty;
            string[] valor;
            string strCampo = String.Empty;
            string strValor = String.Empty;
            string _sql = String.Empty;
            int x = 0;
            JMIUtil objUtil = new JMIUtil();
            StringBuilder cmdSQL = new StringBuilder();

            var schema = GetSchema();

            cmdSQL.Append("INSERT INTO cadastro.ibge(");

            int nroCampo;
            nroCampo = (short)schema.Rows.Count;
            foreach (DataRow campo in schema.Rows)
            {
                x++;
                nomeCampo = campo["ColumnName"].ToString();
                if (nomeCampo.ToLower() == "codigo" && UsaSequenciador) { continue; }
                if (x < nroCampo)
                    strCampo += nomeCampo + ", ";
                else
                    strCampo += nomeCampo;
            }
            cmdSQL.Append(strCampo + ")");
            cmdSQL.Append(" VALUES ");
            for (x = 0; x < lstValor.Count; x++)
            {
                valor = lstValor[x].Split(';');
                
                // Valores fixos
                strValor = "'" + DateTime.Now.ToShortDateString();
                strValor += "',1"; // por enquanto esta fixo
                strValor += ",1"; // por enquanto esta fixo
                strValor += ",'" + DateTime.MinValue.ToShortDateString();
                strValor += "',True";
                strValor += "," + ProximoID.ToString() + ",";
                strValor += valor[2] + ",";
                strValor += "'" + objUtil.RemoveAcento(valor[3]) + "',";
                strValor += valor[0] + ",";
                strValor += "'" + objUtil.RemoveAcento(valor[1]) + "',";
                           
                strValor = strValor.Substring(0, strValor.Length - 1);
                ProximoID++;
                cmdSQL.Append("(" + strValor + "),");
            }
            _sql = cmdSQL.ToString();
            _sql = _sql.Substring(0, _sql.Length - 1);
            return _sql;
        }
  
        private void GeraParametro(ref DbCommand _cmd, mIBGE infoIBGE)
        {
            _cmd.Parameters.Clear();
            int idIbge = infoIBGE.Codigo == 0 ? UtilBD.GetID(EngineBD.GetConexao, "cadastro.ibge", "indice", 0) : infoIBGE.Codigo;

            UtilBD.AdicionaParametro(ref _cmd, "@codigo", idIbge);
            UtilBD.AdicionaParametro(ref _cmd, "@empresa", infoIBGE.Empresa);
            UtilBD.AdicionaParametro(ref _cmd, "@datacadastro", infoIBGE.DataCadastro);
            UtilBD.AdicionaParametro(ref _cmd, "@usuario", infoIBGE.Usuario);
            UtilBD.AdicionaParametro(ref _cmd, "@dataalteracao", infoIBGE.DataAlteracao);
            UtilBD.AdicionaParametro(ref _cmd, "@ativo", infoIBGE.Ativo);
            UtilBD.AdicionaParametro(ref _cmd, "@numero", infoIBGE.Numero);
            UtilBD.AdicionaParametro(ref _cmd, "@municipio", infoIBGE.Municipio);
            UtilBD.AdicionaParametro(ref _cmd, "@coduf", infoIBGE.CodUF);
            UtilBD.AdicionaParametro(ref _cmd, "@uf", infoIBGE.UF);
        }
        #endregion
    }
}
